﻿using SignalProcessLib.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SignalProcessLib
{
    public class RmsCalculation
    {
        /// <summary>
        /// 均方根值RMS计算
        /// </summary>
        /// <param name="data">x坐标可以为空</param>
        /// <returns></returns>
        public double Dispathcer(DataFormat data)
        {
            double r;

            if (data.Unit.Contains("dB"))
            {
                r = SpectrumAmplitudedB(data.Y);
                return r;
            }
            else
            {
                r = SpectrumAmplitude(data.Y);
                return r;
            }
        }
        private double Time(double[] y)
        {
            List<double> yl = new List<double>(y);
            int len = y.Length;
            return Math.Sqrt(yl.Sum(s => Math.Pow(s, 2)) / len);
        }

        /// <summary>
        /// 求幅值谱的均方根值RMS，单位m/s2
        /// </summary>
        /// <param name="y">输入幅值谱，单位m/s2</param>
        /// <returns>返回RMS值，单位与输入的幅值一致</returns>
        private double SpectrumAmplitude(double[] y)
        {
            List<double> amps = new List<double>(y);
            //转换为功率谱
            List<double> powers = amps.Select(a => a / VibrationConstant.AmplitudeRecoveryCoefficient * VibrationConstant.PowerRecoveryCoefficient).ToList();
            //计算自功率谱的能量
            return spectrumLinear(powers);
        }

        /// <summary>
        /// 求幅值谱的均方根值RMS，单位dB
        /// </summary>
        /// <param name="y">输入幅值谱，单位m/s2</param>
        /// <returns>返回RMS值，单位与输入的幅值一致</returns>
        private double SpectrumAmplitudedB(double[] y)
        {
            List<double> ampdb = new List<double>(y);
            ////转换为幅值谱
            //List<double> amps =
            //    ampdb.Select(a => VibrationConstant.Acc0 * Math.Pow(10, a / 20)).ToList();
            ////幅值谱转换为功率谱
            //List<double> powers =
            //    amps.Select(a => a / VibrationConstant.AmplitudeRecoveryCoefficient * VibrationConstant.PowerRecoveryCoefficient).ToList();
            //return spectrumLinear(powers);
            return spectrumdB(ampdb);
        }

        /// <summary>
        /// 求功率谱的均方根值RMS
        /// </summary>
        /// <param name="y">输入功率谱，单位m/s2或db</param>
        /// <returns>返回RMS值，单位与输入的幅值一致</returns>
        private double SpectrumPower(double[] y)
        {
            List<double> powers = new List<double>(y);
            int len = y.Length;
            return Math.Sqrt(2 * (-powers[0] * powers[0] / 2 + powers.Sum(s => Math.Pow(s, 2)) - powers[len - 1] * powers[len - 1] / 2));
        }

        /// <summary>
        /// 线性谱求RMS
        /// </summary>
        /// <param name="y"></param>
        /// <returns></returns>
        private double spectrumLinear(List<double> y)
        {
            int len = y.Count;
            double temp = Math.Sqrt(y.Sum(s => Math.Pow(s, 2)));
            return temp;
        }

        /// <summary>
        /// 对数谱求RMS
        /// </summary>
        /// <param name="y">纵坐标单位为dB</param>
        /// <returns></returns>
        private double spectrumdB(List<double> y)
        {
            int len = y.Count;
            Console.WriteLine(y.Max());
            double temp = 10 * Math.Log10(y.Sum(s => Math.Pow(10, s / 10)));
            return temp;
            //return VibrationConstant.Acc0 * Math.Sqrt(2 * y.Sum(s => Math.Pow(10, s / 10)));
        }
    }
}
